class OpenSourceProject < ActiveRecord::Base
  attr_accessible :name

  include Redmine::SafeAttributes
  #gcm
  #has_many :open_source_project_infos, :class_name => "OpenSourceProjectInfo", :foreign_key => "osp_id", :dependent => :delete_all #, :order => "created_time DESC"
  # has_many :relative_topics, :class_name => 'RelativeMemoToOpenSourceProject', :foreign_key => 'osp_id', :order => "#{RelativeMemoToOpenSourceProject.table_name}.match_weight DESC", :dependent => :destroy
  # has_many :topics, :through => :relative_topics, :class_name => 'RelativeMemo', :conditions => "#{RelativeMemo.table_name}.parent_id IS NULL OR #{RelativeMemo.table_name}.parent_id=0", :order => "#{RelativeMemoToOpenSourceProject.table_name}.match_weight DESC"
  # has_many :tags, :through => :project_tags, :class_name => 'Tag'
  # has_many :project_tags, :class_name => 'ProjectTags'
  # has_many :admin, :through => :masters, :class_name => 'User'
  # has_many :applicants, :class_name => 'User', :through => :apply_tips, :source => :user

  # has_many :bugs_to_osp, :class_name => 'BugToOsp', :foreign_key => 'osp_id', :dependent => :destroy

  has_many :hot_words, :class_name => 'HotWord', :foreign_key => 'osp_id'
  has_many :highcharts, :class_name => 'Highchart', :foreign_key => 'osp_id'
  # 添加项目关联项目的外键 ——by Nigel start
  has_many :relation_recommends, :class_name => "RelationRecommend", :foreign_key => "osp_id"
  has_many :relation_recommends, :class_name => "RelationRecommend", :foreign_key => "relative_osp_id"
  has_many :relation_recommends, :class_name => "SimilityRecommend", :foreign_key => "osp_id"
  has_many :relation_recommends, :class_name => "SimilityRecommend", :foreign_key => "relative_osp_id"
  # 添加项目关联项目的外键 ——by Nigel end
  has_many :open_source_project_popularities, :class_name => 'OpenSourceProjectPopularity', :foreign_key => 'osp_id'
  # has_one :hot_word, :foreign_key => "osp_id"
  #gcm end


  # has_many :topics, :class_name => 'RelativeMemo', :foreign_key => 'osp_id', :conditions => "#{RelativeMemo.table_name}.parent_id IS NULL", :order => "#{RelativeMemo.table_name}.created_time DESC", :dependent => :destroy
  # has_many :relative_memos, :class_name => 'RelativeMemo', :foreign_key => 'osp_id', :dependent => :destroy


  validates_uniqueness_of :name

  acts_as_taggable

  #配置solr索引字段
  searchable do
    text :name, :stored => false
    text :tags, :stored => false
    text :tags_for_search, :stored => false
    text :language, :stored => false
    text :description, :stored => false
    
    integer :filtration
    integer :composite_score
    integer :relative_memos_num

  end

  # followers_num,download_num,view_num其中至少有一个大于1000，然后按照相关帖子数量降序排列
  scope :find_hot_osps, lambda { |args|
    OpenSourceProject.order("composite_score DESC").limit(args)
  }

  # order by relative_memos count
  scope :order_by_match_count, lambda { |args|
    where("#{OpenSourceProject.table_name}.id IN (SELECT osp_id FROM (SELECT osp_id, COUNT(*) AS num FROM #{RelativeMemoToOpenSourceProject.table_name} GROUP BY osp_id ORDER BY num DESC LIMIT 0, ?) AS tmp)", args.to_s)
  }

  scope :like, lambda { |arg|
    if arg.blank?
      where(nil)
    else
      pattern = "%#{arg.to_s.strip.downcase}%"
      #where("LOWER(name) LIKE :p OR LOWER(description) LIKE :p ", :p => pattern)
      where("LOWER(name) LIKE :p", :p => pattern)
    end
  }

  def filter(app_dir, language, created_time)
    filter_app_dir(app_dir).filter_language(language).filter_by_year(created_time)
  end

  def self.filter(app_dir, language, created_time)
    self.filter_app_dir(app_dir).filter_language(language).filter_by_year(created_time)
  end

  scope :filter_app_dir, lambda { |args|
    nil
  }

  scope :filter_language, lambda { |*arg|
    if arg[0].nil?
      where(nil)
    else
      tagged_with(arg) #.order('updated_time desc')
    end
  }

  scope :filter_time, lambda { |args|
    where("YEAR(#{OpenSourceProject.table_name}.created_time) = ?", args) unless args.nil?
  }

  scope :recent, lambda { |start_date = (DateTime.current.months_ago 7), end_date=(DateTime.current.months_ago 4)|
    where("created_time >= :start_date AND created_time <= :end_date",
          {start_date: start_date, end_date: end_date})
  }

  scope :recent_update, lambda { |start_date = (DateTime.current.months_ago 1), end_date=(DateTime.current.months_ago 0)|
    where("updated_time >= :start_date AND updated_time <= :end_date",
          {start_date: start_date, end_date: end_date})
  }

  #gcm
  def self.name_desc_language_like(arg)
    @project_infos=OpenSourceProjectInfo.info_name_desc_language_like(arg)
    osp_ids=[]
    @project_infos.each do |prj_info|
      osp_ids.push(prj_info.osp_id)
    end
    where(id: osp_ids)
  end

  def self.filter_by_year(args)
    return where(nil) if args.blank?
    #@project_infos=OpenSourceProjectInfo.find_by_sql("SELECT osp_id from(SELECT * FROM open_source_project_infos WHERE YEAR(created_time)=#{args} ORDER BY created_time DESC) AS tmp GROUP BY osp_id;")
    @project_infos=OpenSourceProjectInfo.info_filter_by_year(args)
    osp_ids=[]
    @project_infos.each do |prj_info|
      osp_ids.push(prj_info.osp_id)
    end

    where(id: osp_ids)
  end

  def self.order_by_download_num
    order("download_num DESC")
    #@project_infos=OpenSourceProject.open_source_project_infos.last
    #@project_infos=OpenSourceProjectInfo.where("year(created_time)=?",args).group("osp_id").
    #OpenSourceProject.find(@project_infos)
  end


  def self.order_by_view_num
    #return where(nil) if args.blank?
    order("view_num DESC")
    #@project_infos=OpenSourceProject.open_source_project_infos.last
    #@project_infos=OpenSourceProjectInfo.where("year(created_time)=?",args).group("osp_id").
    #OpenSourceProject.find(@project_infos)
  end

  #count projects created_time specified years
  def self.count_num_by_year from, to
    rs=OpenSourceProjectInfo.find_by_sql ["select YEAR(created_time) AS year,"+
                                              " COUNT(*) AS num FROM #{OpenSourceProjectInfo.table_name}"+
                                              " where YEAR(created_time) >= ? AND YEAR(created_time) <= ? "+
                                              " GROUP BY YEAR(created_time)", from, to]
    return rs
  end

  #count projects coming from specified source
  def self.count_num_by_source
    rs=OpenSourceProjectInfo.find_by_sql ["select source,"+
                                              " COUNT(*) AS num FROM #{OpenSourceProjectInfo.table_name}"+
                                              #" where YEAR(created_time) >= ? AND YEAR(created_time) <= ? "+
                                              " GROUP BY source ORDER BY num DESC"]
    return rs
  end

  def short_description(length = 255)
    description.gsub(/^(.{#{length}}[^\n\r]).*$/m, '\1...').strip if description
  end

  def attr_sum
    sum =0
    sum+=followers_num unless followers_num.nil?
    sum+=download_num unless download_num.nil?
    sum+=view_num unless view_num.nil?
    sum+= view_num_ossean unless view_num_ossean.nil?
    sum+= (relative_memos_num/10) unless relative_memos_num.nil?
    sum
    # followers_num+download_num+view_num+view_num_ossean+(relative_memos_num.to_i/100)
  end

  def applied_by?(user)
    self.applies.each do |apply|
      if apply.user_id == user.id
        return true
      end
    end
    false
  end

  def allowed?(user)
    self.applies.each do |apply|
      if apply.user_id == user.id and apply.status == 2
        return true
      end
    end
    false
  end

  def set_apply(user, flag=true)
    flag ? set_filter(user) : remove_filter(user)
  end

  def reset_counters!
    self.class.reset_counters!(id)
  end

  def self.reset_counters!(id)
    osp_id = id.to_i
    # update_all("topic_count = (SELECT COUNT(*) FROM #{RelativeMemo.table_name} WHERE osp_id=#{osp_id} AND parent_id IS NULL)," +
    # " memo_count = (SELECT COUNT(*) FROM #{RelativeMemo.table_name} WHERE osp_id=#{osp_id} AND parent_id IS NOT NULL)," +
    # " last_memo_id = (SELECT MAX(id) FROM #{RelativeMemo.table_name} WHERE osp_id=#{osp_id})",
    # ["id = ?", osp_id])
    update_all("topic_count = (SELECT COUNT(*) FROM #{RelativeMemoToOpenSourceProject.table_name} WHERE osp_id=#{osp_id})",
               # +
               # " memo_count = (SELECT COUNT(*) FROM #{RelativeMemo.table_name} WHERE osp_id=#{osp_id} AND parent_id IS NOT NULL)," +
               # " last_memo_id = (SELECT MAX(id) FROM #{RelativeMemo.table_name} WHERE osp_id=#{osp_id})",
               ["id = ?", osp_id])
  end
  
  def get_tag_list(limit = 7)
    
    #tag_ids = ActsAsTaggableOn::Tagging.select(:tag_id).where("taggable_id = ? AND taggable_type = ? AND disagree_num > ?", obj_id, "OpenSourceProject", 5)
    # ActsAsTaggableOn::Tag.includes(ActsAsTaggableOn::Tagging).where("taggable_id = ? AND taggable_type = ? AND disagree_num > ?", obj_id, "OpenSourceProject", -1)
    #tag_list = ActsAsTaggableOn::Tag.select(:name).where(id:tag_ids)
    # tag_list = ActsAsTaggableOn::Tag.find_by_sql ["SELECT `tags`.* FROM `tags`"+
                                              # " INNER JOIN `taggings` ON `tags`.`id` = `taggings`.`tag_id` WHERE"+
                                              # "`taggings`.`taggable_id` = #{self.id}"+
                                              # " AND `taggings`.`taggable_type` = 'OpenSourceProject'  AND `taggings`.`disagree_num` > 5" +
                                              # " AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL) LIMIT #{limit}"]
    # return tag_list
  end
  
  def get_tag_list_userTag(limit = 9)
    
    
  end
  
end
